home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
MPW_TOOL
/
TOOLS
/
TOOLS_WI
/
ICON_8
/
MEMMON_F
/
MOUTPUT.C
< prev
next >
Wrap
Text File
|
1990-03-02
|
7KB
|
254 lines
/*
* moutput.c: device-independent output routines.
*/
#include "memmon.h"
/*
* Prototypes.
*/
hidden novalue setdisp Params((struct region *r, int key, word addr));
hidden novalue mpaint Params((word addr, word len, int c1, int c2));
static int oldscale = 0; /* previous output scaling */
static int npauses = 0;
static int reply = 0;
/*
* refresh() - redraw screen, initially or after garbage collection.
*/
novalue refresh()
{
word nbytes, newpixels;
int newrows, newscale;
char sbuf[50];
/* set display parameters for each region */
setdisp(&stc, 'f', (word)0);
setdisp(&str, 's', stc.saddr + stc.displ);
setdisp(&blk, 'b', str.saddr + str.displ);
if (textrow > 0)
memheight = height - (TextLines * textrow) - textsep + 1;
else
memheight = height;
/* calc total number of bytes */
nbytes = stc.displ + str.displ + blk.displ;
if (stc.displ + str.displ + blk.displ == 0) {
fprintf(stderr, "%s: no regions selected\n", progname);
exit(ErrorExit);
}
/* calc ideal scaling */
newpixels = (nbytes + granularity - 1) / granularity;
newrows = (newpixels + width - 1) / width;
newscale = memheight / newrows;
/* set scaling, but no more than device or command option maximum */
if (memrow > newscale)
memrow = newscale;
if (memrow <= 0) /* sanity check, and extreme case */
memrow = 1;
if (newrows > memheight)
newrows = memheight;
/* set total number of pixels and minimum y value */
mempixels = (word)newrows * (word)width;
if (mempixels > newpixels)
mempixels = newpixels;
ymin = memheight - newrows * memrow;
if (ymin < 0)
ymin = 0;
/* if layout has changed (including first time), redraw everything */
if (memrow != oldscale) {
devflood(C_Background); /* clear screen */
if (oldscale == 0)
setmap(Marked, C_Marked); /* init color map if first time */
legend(); /* replace legend */
if (title) /* display centered title, if any */
mtext(title, 0, 0 + StatusLength + (TitleLength - strlen(title)) / 2,
C_Title, C_Background);
}
oldscale = memrow;
/* display region sizes and garbage collection counts */
sprintf(sbuf, "%ld + %ld + %ld (%ld+%ld+%ld+%ld)",
(long)stc.length, (long)str.length, (long)blk.length,
(long)nstatic, (long)nstring, (long)nblock, (long)nexplicit);
mtext(sbuf, 0, TextLength - strlen(sbuf) - 1, C_Rsizes, C_Background);
}
/*
* setdisp(region, key, addr) - set display parameters for a region.
*/
static novalue setdisp(r, key, addr)
struct region *r;
int key;
word addr;
{
r->saddr = addr; /* set screen address */
if (index(whichregs, key))
r->displ = r->length; /* if displayed, set length */
else
r->displ = 0; /* else set to zero */
}
/*
* paintblk(region, addr, len, color) - show a block.
*/
novalue paintblk(r, addr, len, color)
struct region *r;
word addr, len;
int color;
{
if (r->displ == 0)
return;
mpaint((r->saddr + addr) / granularity, len / granularity, color, C_Bsep);
}
/*
* paintstr(addr, len, color1, color2) - show n string bytes.
* Each pixel on the display represents multiple bytes. A pixel in which any
* string ends will be color2; pixels corresponding to nonterminal characters
* of one string will be color1. This method makes long strings individually
* distinguishable from each other and from runs of short strings, and allows
* continuous output with no backtracking as the string space is allocated.
*/
novalue paintstr(addr, len, color1, color2)
word addr, len;
int color1, color2;
{
word s, e;
if (str.displ == 0) /* if not displaying strings, return */
return;
/* the start pixel is the first pixel wholly owned by this string */
/* the end pixel is the last pixel even partially reached */
s = (str.saddr + addr + granularity -1) / granularity; /* start */
e = (str.saddr + addr + len - 1) / granularity; /* end */
if (e >= s) /* if any new pixels*/
mpaint(s, e - s + 1, color1, color2);
}
/*
* mpaint(addr, len, colr1, colr2) - paint a block or a string.
*
* Just checks limits, then calls the device-dependent paint routine.
*/
hidden novalue mpaint(addr, len, color1, color2)
word addr, len;
int color1, color2;
{
if (addr < 0 || addr >= mempixels || len <= 0)
return; /* if out of range, return */
if (addr + len > mempixels)
len = mempixels - addr; /* set length to stay within bounds */
devpaint(addr, len, color1, color2); /* paint the device */
}
/*
* gcwait(key, msg) - pause with garbage collection message.
*
* Skips the pause if a -p option didn't include the given key character.
* After one EOF or 'G', never pauses again. Returns whatever pause returns.
*/
int gcwait(key, msg)
int key;
char *msg;
{
if (reply != EOF && reply != 'g' && reply != 'G')
reply = mpause(key, msg);
return reply;
}
/*
* mpause(key, msg) - pause for response (or, in batchmode, print display).
*
* Skips the pause if a -p option didn't include the given key character.
* Returns the last character before '\n', 0 if none, or EOF.
*/
int mpause(key, msg)
int key;
char *msg;
{
static int c1, c2;
if (!index(whenpause, key)) /* if no pause/print of this display */
return 0;
npauses++; /* count this visit */
if (batchmode) { /* if batch, output snapshot */
mstatus(msg, C_Prompt); /* set prompt message */
devsnap(); /* write frame */
mstatus("", C_Background); /* clear the prompt */
if (npauses == pauselimit) /* if limit hit, quit now */
mquit(NormalExit);
return 0;
}
if (ttyi == NULL || c1 == EOF) { /* if no tty, or EOF already seen */
c1 = EOF; /* fake EOF for return */
return EOF;
}
else {
fprintf(ttyo, "memmon pause: %s: ", msg); /* issue prompt */
fflush(ttyo);
mstatus(msg, C_Prompt); /* also post on screen*/
devflush();
c1 = 0;
while ((c2 = getc(ttyi)) != '\n' && c2 != '\r') /* get char up to CR */
if (c2 == EOF || c2 == '\04') { /* handle eof */
c1 = EOF;
break;
}
else
c1 = c2; /* save previous char */
}
if (c1 == 'q' || npauses == pauselimit)
mquit(NormalExit); /* quit on 'q' or if limit hit */
mstatus("", C_Background); /* clear the prompt */
return c1; /* return char before CR */
}
/*
* mstatus(msg, color) - post status message, erasing previous one.
*/
novalue mstatus(msg, color)
char *msg;
int color;
{
char buf[StatusLength];
int i;
char *p;
for (i = 0, p = buf; i < StatusLength-1; i++)
if (*msg)
*p++ = *msg++;
else
*p++ = ' ';
*p++ = '\0';
mtext(buf, 0, 0, color, C_Background);
}
/*
* mtext(string, row, col, fgcolr, bgcolr) - display text in colored box.
*
* Just checks that we haven't suppressed the text, then calls devtext().
*/
novalue mtext(s, row, col, fg, bg)
char *s;
int row, col, fg, bg;
{
if (textrow > 0)
devtext(s, row, col, fg, bg);
}